Security News
ESLint is Now Language-Agnostic: Linting JSON, Markdown, and Beyond
ESLint has added JSON and Markdown linting support with new officially-supported plugins, expanding its versatility beyond JavaScript.
@dldc/erreur
Advanced tools
Type safe custom errors
In JavaScript and TypeScript you can throw anything so when you catch something you don't know what it is which make it hard to properly handle errors.
One way to fix this is to create custom classes that extends the Error class
class HttpError extends Error {
// ...
}
try {
// ...
} catch (error) {
if (error instanceof HttpError) {
// ...
}
}
This works but it has a few drawbacks:
Error
class requires some tricks to make it work properly (Object.setPrototypeOf(this, new.target.prototype);
)To solve these issue, this librairy expose a single custom error class called Erreur
(error in french) that extends the native Error
class. This class can contain data but in order to ensure type safety, you cannot access this data directly. Instead, you must use a key that can be created using the Key.define()
function.
Note Internally, the Erreur
class uses @dldc/stack
to store the data. You probably want to read the documentation of this package first to better understand how it works.
Here is a simple example:
import { ErreurKey, Erreur } from '@dldc/erreur';
// Define a key with the type of the data (`number` in this case) and a function to "instantiate" the Erreur
const StatusCodeErreur = ErreurKey.define<number>('StatusCode')((provider, status: number) => {
return Erreur.create().with(provider(status));
});
// Create a new Erreur with the number value
const err = StatusCodeErreur.create(500);
// you can also extends en existing error to add the value
const errBase = Erreur.create();
const err1 = errBase.with(StatusCodeErreur.Provider(500));
// err, errBase and err1 are all Erreur instances
expect(err).toBeInstanceOf(Erreur);
expect(errBase).toBeInstanceOf(Erreur);
expect(err1).toBeInstanceOf(Erreur);
// Get data from the Erreur
const statusCode = err.get(StatusCodeErreur.Consumer);
expect(statusCode).toBe(500); // statusCode is typed as number
Erreur.create
Create a new Erreur
instance. You can optionally pass a message:
const err1 = Erreur.create();
const err2 = Erreur.create('Something went wrong');
Note: Do not use new Erreur()
to create an Erreur
instance, it will not work properly.
Erreur.createWith
Create a new Erreur
instance with data. This method accepts a Key
and the corresponding value and returns a new Erreur
instance:
const StatusCodeKey = Key.create<number>('StatusCode');
const err = Erreur.createWith(StatusCodeKey, 500);
Erreur.createFromError
Create a new Erreur
instance from an existing Error
instance, it will reuse the message of the error:
const err1 = Erreur.createFromError(new Error('Something went wrong'));
Erreur.createFromUnknown
Create an error from any value, if the value is an Error
instance it will call Erreur.createFromError
, otherwise it the value is converted to a string and used as the message of the error:
const err1 = Erreur.createFromUnknown(anyValue);
ErreurKey.define
TODO
ErreurKey.defineWithDefault
TODO
ErreurKey.defineEmpty
TODO
erreur.with(...providers)
Use the with
method to add data to an Erreur
instance. This method accepts any number of Provider
declaration and returns a new Erreur
instance:
const err1 = Erreur.create().with(MyErrorKey.Provider('Hello'));
erreur.merge(otherErreur)
erreur.mergeOn(otherErreur)
erreur.get(consumer)
erreur.getOrFail(consumer)
erreur.has(consumer)
Erreur.is
Check if a value is an Erreur
instance:
const err = Erreur.create();
const isErr = Erreur.is(err); // true
Note: this is the same as using instanceof Erreur
Erreur.wrap
and Erreur.wrapAsync
Wrap a function to make sure it either returns a value or throws an Erreur
instance. Not that this function does not care about what is inside the Erreur
instance, it only checks that it is an instance of Erreur
.
Erreur.resolve
and Erreur.resolveAsync
Same as Erreur.wrap
and Erreur.wrapAsync
but returns the Erreur
instance instead of throwing it.
You can override the message of an Erreur
using the MessageKey
key:
import { Erreur, MessageKey } from '@dldc/erreur';
const err1 = Erreur.create('Something went wrong');
const err2 = err1.with(MessageKey.Provider('Something went really wrong'));
// A shortcut is also available
const err3 = err2.withMessage('Something went really wrong');
You can override the name of an Erreur
using the NameKey
key:
import { Erreur, NameKey } from '@dldc/erreur';
const err1 = Erreur.create('Something went wrong');
const err2 = err1.with(NameKey.Provider('MyErreur'));
// A shortcut is also available
const err3 = err2.withName('MyErreur');
It can be useful to create a function that returns an Erreur
instance for each key:
import { Key, Erreur } from '@dldc/erreur';
const StatusCodeKey = Key.create<number>('StatusCode');
const createStatusCodeError = (statusCode: number) => {
return Erreur.createWith(StatusCodeKey, statusCode);
};
const err = createStatusCodeError(500);
Using the pattern above, you can "extends" an other key:
import { Key, Erreur } from '@dldc/erreur';
const NotFoundKey = Key.createEmpty('NotFound');
const createNotFound = () => {
return createStatusCodeError().with(NotFoundKey.Provider());
};
const err = createNotFound();
You can handle many errors with a single key using union types:
type FetchError =
| { type: 'NetworkError'; error: any }
| { type: 'ParseError'; content: string }
| { type: 'ResponseNotOk'; response: any };
const FetchErrorType = createErrorType<FetchError>({ name: 'FetchError' });
FAQs
Type safe custom errors
The npm package @dldc/erreur receives a total of 7 weekly downloads. As such, @dldc/erreur popularity was classified as not popular.
We found that @dldc/erreur demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
ESLint has added JSON and Markdown linting support with new officially-supported plugins, expanding its versatility beyond JavaScript.
Security News
Members Hub is conducting large-scale campaigns to artificially boost Discord server metrics, undermining community trust and platform integrity.
Security News
NIST has failed to meet its self-imposed deadline of clearing the NVD's backlog by the end of the fiscal year. Meanwhile, CVE's awaiting analysis have increased by 33% since June.